package cate.game.activity.continuousrecharge;

import cate.common.table.activity.continuousrecharge.level.ContinuousRechargeLevelRow;
import cate.common.table.activity.continuousrecharge.task.ContinuousRechargeTaskRow;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDOperation;
import cate.common.util.GameResult;
import cate.common.util.TimeTool;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.continuousrecharge.msg.ContinuousRechargeActivityInfoResp;
import cate.game.activity.merge.msg.MergeContinuousRechargeActivityInfoResp;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.role.Role;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@NoteClass("连续充值活动")
public class ContinuousRechargeActivity extends RoleActivitySingle {
    @NoteField("是否假装关闭")
    public boolean close;
    @NoteField("今日充值数")
    public long paySum;
    @NoteField("档位信息")
    public Map<Integer, ContinuousRechargeActivityLevelPO> levels;
    @NoteField("任务信息")
    public Map<Integer, Boolean> tasks;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (levels == null) {
            levels = new HashMap<>();
        }
        if (tasks == null) {
            tasks = new HashMap<>();
        }
        levels.values().forEach(level -> level.initialize(this));
        role.getActivity().registerRecharge(this, this::onRecharge);
    }

    @Override
    public void excelCheck() {
        Map<Integer, ContinuousRechargeLevelRow> allLevels = getAllLevels();
        if (allLevels == null || allLevels.isEmpty()) {
            levels.clear();
        } else {
            levels.entrySet().removeIf(entry -> !allLevels.containsKey(entry.getKey()));
            allLevels.entrySet().stream().filter(entry -> !levels.containsKey(entry.getKey()))
                    .forEach(entry -> levels.put(entry.getKey(), new ContinuousRechargeActivityLevelPO(this, entry.getKey())));
        }
        Map<Integer, ContinuousRechargeTaskRow> allTasks = getAllTaskConfigs();
        if (allTasks == null || allTasks.isEmpty()) {
            tasks.clear();
        } else {
            tasks.entrySet().removeIf(entry -> getTaskConfig(entry.getKey()) == null);
            allTasks.entrySet().stream().filter(entry -> !tasks.containsKey(entry.getKey()))
                    .forEach(entry -> tasks.put(entry.getKey(), false));
        }
    }

    public void noticeUpdate() {
        if (close) {
            return;
        }
        switch (funcId()) {
            case GDFunc.ACT_CONTINUOUS_RECHARGE: {
                role.sendNow(new ContinuousRechargeActivityInfoResp(this));
            }
            break;
            case GDFunc.MergeAct.MERGE_ACT_DAILY_RECHARGE:
                role.sendNow(new MergeContinuousRechargeActivityInfoResp(this));
                break;
            default:
                break;
        }
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        if (close) {
            return;
        }
        paySum = 0;
        levels.values().forEach(level -> level.onDaySpan(silence));
    }

    @Override
    public void onRoleOpen() {
        Map<Integer, ContinuousRechargeTaskRow> allTasks = getAllTaskConfigs();
        if (allTasks == null) {
            return;
        }
        int day = TimeTool.getDistanceDays(game().time.now(), base.endTime);
        int rechargeDay = allTasks.values().stream()
                .collect(Collectors.summarizingInt(a -> a.needDay))
                .getMax();
        if (rechargeDay > day) {
            close = true;
        }
    }

    @Override
    public void onRoleEnd() {
        close = false;
        paySum = 0;
        levels.clear();
        tasks.clear();
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    /**
     * 获取所有档位配置
     */
    @JsonIgnore
    private Map<Integer, ContinuousRechargeLevelRow> getAllLevels() {
        switch (funcId()) {
            case GDFunc.MergeAct.MERGE_ACT_DAILY_RECHARGE: {
                Map<Integer, ContinuousRechargeLevelRow> retMap = new HashMap<>();
                role.getGame().table.mergeCR.level.getList().stream()
                        .filter(row -> row.configTid == configTid())
                        .forEach(row -> retMap.put(row.level, row));
                return retMap;
            }
            case GDFunc.ACT_CONTINUOUS_RECHARGE: {
                Map<Integer, ContinuousRechargeLevelRow> retMap = new HashMap<>();
                role.getGame().table.continuousRecharge.level.getList().stream()
                        .filter(row -> row.configTid == configTid())
                        .forEach(row -> retMap.put(row.level, row));
                return retMap;
            }
        }
        return null;
    }

    /**
     * 获取单档配置
     *
     * @param level 档位
     */
    @JsonIgnore
    public ContinuousRechargeLevelRow getLevelConfig(int level) {
        Map<Integer, ContinuousRechargeLevelRow> rows = getAllLevels();
        if (rows == null) {
            return null;
        }
        return rows.get(level);
    }

    /**
     * 获取所有分项配置
     */
    @JsonIgnore
    private Map<Integer, ContinuousRechargeTaskRow> getAllTaskConfigs() {
        switch (funcId()) {
            case GDFunc.MergeAct.MERGE_ACT_DAILY_RECHARGE: {
                Map<Integer, ContinuousRechargeTaskRow> retMap = new HashMap<>();
                role.getGame().table.mergeCR.task.getList().stream()
                        .filter(row -> row.configTid == configTid())
                        .forEach(row -> retMap.put(row.id, row));
                return retMap;
            }
            case GDFunc.ACT_CONTINUOUS_RECHARGE: {
                Map<Integer, ContinuousRechargeTaskRow> retMap = new HashMap<>();
                role.getGame().table.continuousRecharge.task.getList().stream()
                        .filter(row -> row.configTid == configTid())
                        .forEach(row -> retMap.put(row.id, row));
                return retMap;
            }
        }
        return null;
    }


    /**
     * 获取单项配置
     *
     * @param tid 配置ID
     */
    @JsonIgnore
    private ContinuousRechargeTaskRow getTaskConfig(int tid) {
        switch (funcId()) {
            case GDFunc.MergeAct.MERGE_ACT_DAILY_RECHARGE: {
                return role.getGame().table.mergeCR.task.get(tid);
            }
            case GDFunc.ACT_CONTINUOUS_RECHARGE: {
                return role.getGame().table.continuousRecharge.task.get(tid);
            }
        }
        return null;
    }

    /**
     * 分项领奖操作ID
     */
    @JsonIgnore
    public int getTaskOperation() {
        switch (funcId()) {
            case GDFunc.MergeAct.MERGE_ACT_DAILY_RECHARGE:
                return GDOperation.MERGE_CONTINUOUS_RECHARGE_TASK;
            case GDFunc.ACT_CONTINUOUS_RECHARGE:
                return GDOperation.ACT_CONTINUOUS_RECHARGE_TASK;
        }
        return GDOperation.NULL;
    }

    /**
     * 累计领奖操作ID
     */
    @JsonIgnore
    public int getAddUpOperation() {
        switch (funcId()) {
            case GDFunc.MergeAct.MERGE_ACT_DAILY_RECHARGE:
                return GDOperation.MERGE_CONTINUOUS_RECHARGE_ADD_UP;
            case GDFunc.ACT_CONTINUOUS_RECHARGE:
                return GDOperation.ACT_CONTINUOUS_RECHARGE_ADD_UP;
        }
        return GDOperation.NULL;
    }

    /**
     * 充值触发
     *
     * @param payNum 充值数量
     */
    public void onRecharge(long payNum) {
        if (close) {
            return;
        }
        paySum += payNum;
        levels.values().forEach(ContinuousRechargeActivityLevelPO::checkPay);
        noticeUpdate();
    }

    /**
     * 领取单项奖励
     *
     * @param tid 配置ID
     * @return 领取结果 携带活动类
     */
    public GameResult<ContinuousRechargeActivity> onGetTaskReward(int tid) {
        GameResult<ContinuousRechargeActivity> r = new GameResult<>();
        r.data = this;
        if (close) {
            return r.fail("活动没开啊SB!");
        }
        if (!tasks.containsKey(tid)) {
            return r.fail("配置不存在");
        }
        if (tasks.get(tid)) {
            return r.fail("奖励已领取");
        }
        ContinuousRechargeTaskRow taskRow = getTaskConfig(tid);
        if (taskRow == null) {
            return r.fail("不存在配置");
        }
        if (!levels.containsKey(taskRow.level)) {
            return r.fail("找不到档位");
        }
        ContinuousRechargeActivityLevelPO levelPO = levels.get(taskRow.level);
        if (levelPO.day < taskRow.needDay) {
            return r.fail("充值天数不足");
        }
        MixRes reward = new MixRes(taskRow.rewardStr);
        if (reward.isEmpty()) {
            return r.fail("奖励配置错误");
        }
        tasks.put(tid, true);
        EcResult<?> exe = new MixResAdder().setRes(reward)
                .setDialogReward(true)
                .setSendMailWhenFull(true)
                .setOperation(getTaskOperation())
                .setOperationSub(tid)
                .exe(role);
        return r.success();
    }

    /**
     * 领取累计奖励
     *
     * @param level 档位
     * @return 领取结果 携带活动类
     */
    public EcResult<ContinuousRechargeActivity> onGetPrivilegeReward(int level) {
        EcResult<ContinuousRechargeActivity> r = new EcResult<>();
        r.data = this;
        if (close) {
            return r.fail("活动没开啊SB!");
        }
        if (!levels.containsKey(level)) {
            return r.fail("档位不存在");
        }
        return levels.get(level).onGetAddUpReward();
    }
}
